﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.CApCableStatusAnalysis
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using EngineeringInternalExtension;
using System;
using System.Collections.Generic;
using System.Linq;
using Tecnomatix.Engineering;
using Tecnomatix.Engineering.PrivateImplementationDetails;


namespace DnProcessSimulateCommands;

public class CApCableStatusAnalysis
{
  internal CApCableStatusAnalysis(
    ICApFLEXCableAttributeViewModel attributModel,
    CApCableFrameAttachmentRetriever frameAttachmentRetriever)
  {
    this.AttributeModel = attributModel;
    this.CableFrameAttachmentRetriever = frameAttachmentRetriever;
    this.CableFrameAttachmentRetriever = frameAttachmentRetriever;
  }

  public ICApFLEXCableAttributeViewModel AttributeModel { get; }

  public CUiFLEXCreationMode CreationMode => this.AttributeModel.CreationMode;

  public double FulcrumLength => this.AttributeModel.FulcrumLength;

  public double Length => this.AttributeModel.Length;

  public ITxLocatableObject StartFrame => this.AttributeModel.StartFrame;

  public ITxLocatableObject EndFrame => this.AttributeModel.EndFrame;

  public ITxLocatableObject PassNearFrame => this.AttributeModel.PassNearFrame;

  public ITxPointCloudLayer OptimizationPointCloudLayer
  {
    get => this.AttributeModel.OptimizationPointCloudLayer;
  }

  public List<CApFLEXAttachment> AttachmentDataList => this.AttributeModel.RawAttachmentList();

  public double Radius => this.AttributeModel.Radius;

  public bool IsLengthOptimizationEnabled
  {
    get
    {
      return this.CreationMode == CUiFLEXCreationMode.FROM_POINT_CLOUD && this.AttributeModel.IsLengthOptimizationActivated;
    }
  }

  public bool IsRadiusOptimizationEnabled
  {
    get
    {
      return this.CreationMode == CUiFLEXCreationMode.FROM_POINT_CLOUD && this.AttributeModel.IsRadiusOptimizationActivated;
    }
  }

  public bool IsCableInEquipment => this.AttributeModel.CableScopeStatus.IsCableInEquipment;

  public ITxObject ParentEquipment => this.AttributeModel.CableScopeStatus.ParentEquipment;

  public double MinimalLengthBetweenAttachments
  {
    get => TxCableDataValidator.GetMinimalLengthBetweenAttachments(this.Radius, this.FulcrumLength);
  }

  internal CApCableFrameAttachmentRetriever CableFrameAttachmentRetriever { get; private set; }

  public List<CApFLEXAttachment> ComputeAttachmentsAlongCableOrderedList()
  {
    return this.AttachmentDataList.Where<CApFLEXAttachment>((Func<CApFLEXAttachment, bool>) (a => a.Location == CApFLEXAttachmentLocation.AlongCable)).OrderBy<CApFLEXAttachment, double>((Func<CApFLEXAttachment, double>) (a => a.LengthFromStart)).ToList<CApFLEXAttachment>();
  }

  private static TxTypeFilter GetAttachementFrameFilter()
  {
    TxTypeFilter attachementFrameFilter = new TxTypeFilter(typeof (TxComponent));
    attachementFrameFilter.AddIncludedType(typeof (TxLogicalGroup));
    attachementFrameFilter.AddIncludedType(typeof (TxGun));
    attachementFrameFilter.AddIncludedType(typeof (TxRobot));
    attachementFrameFilter.AddIncludedType(typeof (TxTcTypeDefinition));
    attachementFrameFilter.AddIncludedType(typeof (TxKinematicLink));
    attachementFrameFilter.AddIncludedType(typeof (TxServoGun));
    attachementFrameFilter.AddIncludedType(typeof (ITxContinuousOperation));
    attachementFrameFilter.AddIncludedType(typeof (TxWeldPoint));
    attachementFrameFilter.AddIncludedType(typeof (TxTcTypeDefinition));
    attachementFrameFilter.AddIncludedType(typeof (TxCompoundResource));
    attachementFrameFilter.AddIncludedType(typeof (TxCompoundPartEx));
    attachementFrameFilter.AddIncludedType(typeof (TxPartInstanceEx));
    attachementFrameFilter.AddIncludedType(typeof (TxPartEx));
    attachementFrameFilter.AddIncludedType(typeof (TxFrame));
    attachementFrameFilter.AddIncludedType(typeof (TxGripper));
    attachementFrameFilter.AddIncludedType(typeof (TxDevice));
    attachementFrameFilter.AddExcludedType(typeof (TxMfgFeature));
    attachementFrameFilter.AddExcludedType(typeof (TxWeldPoint));
    attachementFrameFilter.AddExcludedType(typeof (TxContinuousRoboticOperation));
    return attachementFrameFilter;
  }

  public bool IsStartFrameProperlyAttachedToEquipment()
  {
    return !this.IsCableInEquipment || CApCableUtility.IsObjectInsideEquipment(this.AttributeModel.StartAttachPartTo, this.ParentEquipment);
  }

  public bool IsEndFrameProperlyAttachedToEquipment()
  {
    return !this.IsCableInEquipment || CApCableUtility.IsObjectInsideEquipment(this.AttributeModel.EndAttachPartTo, this.ParentEquipment);
  }

  public bool AreStartEndFrameAttachedToSameRobot()
  {
    bool sameRobot = true;
    TxRobot robot1 = (TxRobot) null;
    TxRobot robot2 = (TxRobot) null;
    if (this.StartFrame != null)
    {
      sameRobot = true;
      ITxLocatableObject startAttachPartTo = this.AttributeModel.StartAttachPartTo as ITxLocatableObject;
      ITxLocatableObject endAttachPartTo = this.AttributeModel.EndAttachPartTo as ITxLocatableObject;
      if (this.AttributeModel.StartAttachPartTo != null)
        this.CableFrameAttachmentRetriever.RetrieveAttachingRobot(this.StartFrame, this.AttributeModel.StartAttachPartTo, out robot1);
      if (this.AttributeModel.EndAttachPartTo != null)
        this.CableFrameAttachmentRetriever.RetrieveAttachingRobot(this.EndFrame, this.AttributeModel.EndAttachPartTo, out robot2);
      if (TxRobot.op_Inequality(robot1, (ITxObject) robot2) && TxRobot.op_Inequality(robot1, (ITxObject) null) && TxRobot.op_Inequality(robot2, (ITxObject) null))
        sameRobot = false;
    }
    return sameRobot;
  }

  public bool AreAttachmentsAttachedToRobot(ITxObject robot)
  {
    bool robot1 = true;
    foreach (CApFLEXAttachment attachmentData in this.AttachmentDataList)
    {
      TxRobot robot2 = (TxRobot) null;
      this.CableFrameAttachmentRetriever.RetrieveAttachingRobot(attachmentData.FixedFrame, out robot2);
      if (TxRobot.op_Inequality(robot2, robot))
      {
        robot1 = false;
        break;
      }
    }
    return robot1;
  }

  public bool AreAttachementAttachmentsFrameValid()
  {
    bool flag = true;
    foreach (CApFLEXAttachment attachmentData in this.AttachmentDataList)
    {
      TxRobot robot = (TxRobot) null;
      this.CableFrameAttachmentRetriever.RetrieveAttachingRobot(attachmentData.FixedFrame, out robot);
      if (TxRobot.op_Equality(robot, (ITxObject) null))
      {
        flag = false;
        break;
      }
      if (attachmentData is CApFLEXRetractSystemAttachmentType3)
      {
        robot = (TxRobot) null;
        this.CableFrameAttachmentRetriever.RetrieveAttachingRobot((attachmentData as CApFLEXRetractSystemAttachmentType3).SecondaryFixedFrame, out robot);
        if (TxRobot.op_Equality(robot, (ITxObject) null))
        {
          flag = false;
          break;
        }
      }
    }
    return flag;
  }

  public bool IsAttachmentFulcrumLengthValid(
    out double fulcrumMinDistance,
    out int invalidAttachmentIndex)
  {
    bool flag = true;
    invalidAttachmentIndex = -1;
    fulcrumMinDistance = 0.0;
    double betweenAttachedFrames = this.ComputeMinLengthBetweenAttachedFrames();
    foreach (CApFLEXAttachment attachmentData in this.AttachmentDataList)
    {
      if (betweenAttachedFrames < attachmentData.AttachmentEntryFulcrumLength * 4.0)
      {
        invalidAttachmentIndex = attachmentData.IndexFixedFrame;
        fulcrumMinDistance = betweenAttachedFrames / 4.0;
        flag = false;
        break;
      }
    }
    return flag;
  }

  public bool IsFulcrumLengthValid(out double fulcrumMinDistance)
  {
    fulcrumMinDistance = 0.0;
    double betweenAttachedFrames = this.ComputeMinLengthBetweenAttachedFrames();
    bool flag = betweenAttachedFrames > this.FulcrumLength * 4.0;
    if (!flag)
      fulcrumMinDistance = betweenAttachedFrames / 4.0;
    return flag;
  }

  private double ComputeMinLengthBetweenAttachedFrames()
  {
    double val2 = this.Length;
    if (this.AttachmentDataList != null && this.AttachmentDataList.Count != 0)
    {
      double num = 0.0;
      List<CApFLEXAttachment> cableOrderedList = this.ComputeAttachmentsAlongCableOrderedList();
      if (cableOrderedList.Any<CApFLEXAttachment>())
      {
        foreach (CApFLEXAttachment capFlexAttachment in cableOrderedList)
        {
          val2 = Math.Min(capFlexAttachment.LengthFromStart - num, val2);
          num = capFlexAttachment.LengthFromStart;
        }
        val2 = Math.Min(this.Length - cableOrderedList.Last<CApFLEXAttachment>().LengthFromStart, val2);
      }
    }
    return val2;
  }

  public bool ArePercentageLengthBetweenAttachmentsValid(
    out CApFLEXAttachmentErrorMessage errorMessage)
  {
    bool flag1 = true;
    errorMessage = new CApFLEXAttachmentErrorMessage();
    List<CApFLEXAttachment> cableOrderedList = this.ComputeAttachmentsAlongCableOrderedList();
    if (cableOrderedList.Any<CApFLEXAttachment>())
    {
      double betweenAttachments = this.MinimalLengthBetweenAttachments;
      double num = 0.0;
      bool flag2 = true;
      List<CApFLEXAttachment>.Enumerator enumerator = cableOrderedList.GetEnumerator();
      while (flag1 && enumerator.MoveNext())
      {
        CApFLEXAttachment current = enumerator.Current;
        if (current.LengthFromStart - num < betweenAttachments)
        {
          flag1 = false;
          errorMessage.DistanceFromAttachment1 = betweenAttachments;
          errorMessage.AttachmentErrorType = !flag2 ? CApFLEXAttachmentErrorMessage.EAttachmentErrorType.AttachmentAttachmentPercentageLengthError : CApFLEXAttachmentErrorMessage.EAttachmentErrorType.StartAttachmentPercentageLengthError;
        }
        else
          num = current.LengthFromStart;
        flag2 = false;
      }
      if (flag1 && this.Length - cableOrderedList.Last<CApFLEXAttachment>().LengthFromStart < betweenAttachments)
      {
        errorMessage.DistanceFromAttachment1 = betweenAttachments;
        errorMessage.AttachmentErrorType = CApFLEXAttachmentErrorMessage.EAttachmentErrorType.AttachmentEndPercentageLengthError;
        flag1 = false;
      }
    }
    return flag1;
  }

  public bool DoesContainOnlyZAxisFreeRotatingAttachments()
  {
    return CApCableUtility.DoAttachmentsContainOnlyZAxisFreeRotatingAttachments(this.AttachmentDataList);
  }

  public bool AreAttachmentsLengthSmallerThanCableLength()
  {
    bool flag = true;
    if (this.AttachmentDataList != null)
    {
      foreach (CApFLEXAttachment attachmentData in this.AttachmentDataList)
      {
        if (attachmentData.LengthFromStart > this.Length)
        {
          flag = false;
          break;
        }
      }
    }
    return flag;
  }

  public bool IsAttachmentLengthConsistentWithSecondaryAttachmentLength(
    out CApFLEXAttachmentErrorMessage errorMessage)
  {
    bool flag = true;
    errorMessage = new CApFLEXAttachmentErrorMessage();
    if (this.AttachmentDataList != null)
    {
      for (int index = 0; flag && index < this.AttachmentDataList.Count; ++index)
      {
        if (this.AttachmentDataList[index] is CApFLEXRetractSystemAttachmentType3 && (this.AttachmentDataList[index] as CApFLEXRetractSystemAttachmentType3).LengthFromStart <= (this.AttachmentDataList[index] as CApFLEXRetractSystemAttachmentType3).SecondaryLengthFromStart)
        {
          errorMessage.AttachmentErrorType = CApFLEXAttachmentErrorMessage.EAttachmentErrorType.AttachmentPrimaryDistanceInconsistencyError;
          errorMessage.AttachmentType = CApFLEXAttachmentType.RetractSystemType3;
          errorMessage.AttachmentRank = index;
          errorMessage.DistanceFromAttachment1 = (this.AttachmentDataList[index] as CApFLEXRetractSystemAttachmentType3).SecondaryLengthFromStart;
          flag = false;
        }
      }
    }
    return flag;
  }

  public bool IsAttachmentLengthConsistentWithRetractSystem(
    out CApFLEXAttachmentErrorMessage errorMessage)
  {
    bool flag = true;
    errorMessage = new CApFLEXAttachmentErrorMessage();
    if (this.AttachmentDataList != null)
    {
      for (int index = 0; flag && index < this.AttachmentDataList.Count - 1; ++index)
      {
        if (this.IsPointAttachment(this.AttachmentDataList[index]) && this.IsRetractSystemAttachment(this.AttachmentDataList[index + 1]))
        {
          double lowerBound = 0.0;
          double upperBound = 0.0;
          double lengthFromStart1 = this.AttachmentDataList[index].LengthFromStart;
          double lengthFromStart2 = this.AttachmentDataList[index + 1].LengthFromStart;
          double maxRetractedLength = (this.AttachmentDataList[index + 1] as CApFLEXRetractSystemAttachment).MaxRetractedLength;
          if (this.AttachmentDataList[index + 1].AttachmentType == CApFLEXAttachmentType.RetractSystemType2)
          {
            flag = CApCableAttachmentStatusAnalysis.IsPointAndRetractSystemAttachementType2DistanceValid(this.MinimalLengthBetweenAttachments, maxRetractedLength, lengthFromStart2, lengthFromStart1, out lowerBound, out upperBound);
          }
          else
          {
            double secondaryLengthFromStart = (this.AttachmentDataList[index + 1] as CApFLEXRetractSystemAttachmentType3).SecondaryLengthFromStart;
            flag = CApCableAttachmentStatusAnalysis.IsPointAndRetractSystemAttachementType3DistanceValid(this.MinimalLengthBetweenAttachments, maxRetractedLength, lengthFromStart2, secondaryLengthFromStart, lengthFromStart1, out lowerBound, out upperBound);
          }
          if (!flag)
          {
            errorMessage.AttachmentErrorType = CApFLEXAttachmentErrorMessage.EAttachmentErrorType.AttachmentDistanceInconsistencyWithRetractSystemError;
            errorMessage.AttachmentType = this.AttachmentDataList[index].AttachmentType;
            errorMessage.AttachmentRank = index;
            errorMessage.DistanceFromAttachment1 = lowerBound;
          }
        }
      }
    }
    return flag;
  }

  public bool IsPassNearDistanceValid(out double validDistance)
  {
    bool flag = true;
    validDistance = 0.0;
    if (this.PassNearFrame != null)
    {
      validDistance = this.Length * 2.0;
      double distance1 = 0.0;
      CApCableUtility.ComputeDistanceBetweenFrames(this.StartFrame, this.PassNearFrame, out distance1);
      flag = distance1 < validDistance;
      if (flag)
      {
        double distance2 = 0.0;
        CApCableUtility.ComputeDistanceBetweenFrames(this.EndFrame, this.PassNearFrame, out distance2);
        flag = distance2 < validDistance;
      }
    }
    return flag;
  }

  private bool IsPointAttachment(CApFLEXAttachment attachment)
  {
    return attachment.AttachmentType == CApFLEXAttachmentType.Fixed || attachment.AttachmentType == CApFLEXAttachmentType.Rotating || attachment.AttachmentType == CApFLEXAttachmentType.RotatingSliding;
  }

  private bool IsRetractSystemAttachment(CApFLEXAttachment attachment)
  {
    return attachment.AttachmentType == CApFLEXAttachmentType.RetractSystemType2 || attachment.AttachmentType == CApFLEXAttachmentType.RetractSystemType3;
  }

  public static string AttachmentErrorMessage(
    CApFLEXAttachmentErrorMessage attachmentErrorMessage)
  {
    return attachmentErrorMessage.GetErrorMessage();
  }

  public static double ComputeValueWithCurrentLinearUnit(double value)
  {
    return value / TxApplication.Options.Units.LinearMultiplier;
  }
}
